package com.jsy.common.util.license;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

/**
 * 非对称加密工具类
 *      * keytool -genkeypair -keyalg RSA -keysize 2048 -validity 3650 -keystore keystore.jks -storepass 123456 -keypass 123456 -alias key
 */
public class AsymmetricEncryptionUtil {
    // 算法名称
    private static final String ALGORITHM = "RSA";
    // 签名算法名称
    private static final String SIGN_ALGORITHM = "SHA256withRSA";

    /**
     * 生成密钥对
     * @return Map，包含公钥和私钥
     * @throws Exception 异常
     */
    public static Map<String, String> generateKeyPair() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHM);
        keyPairGen.initialize(2048);
        KeyPair keyPair = keyPairGen.generateKeyPair();

        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        String publicKeyBase64 = Base64.getEncoder().encodeToString(publicKey.getEncoded());
        String privateKeyBase64 = Base64.getEncoder().encodeToString(privateKey.getEncoded());

        Map<String, String> keyMap = new HashMap<>();
        keyMap.put("publicKey", publicKeyBase64);
        keyMap.put("privateKey", privateKeyBase64);
        return keyMap;
    }

    /**
     * 公钥加密
     * @param data 待加密数据
     * @param publicKeyBase64 公钥（Base64编码）
     * @return 加密后的数据（Base64编码）
     * @throws Exception 异常
     */
    public static String encryptByPublicKey(String data, String publicKeyBase64) throws Exception {
        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyBase64);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        PublicKey publicKey = keyFactory.generatePublic(keySpec);

        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedData = cipher.doFinal(data.getBytes("UTF-8"));
        return Base64.getEncoder().encodeToString(encryptedData);
    }

    /**
     * 私钥解密
     * @param encryptedData 待解密数据（Base64编码）
     * @param privateKeyBase64 私钥（Base64编码）
     * @return 解密后的数据
     * @throws Exception 异常
     */
    public static String decryptByPrivateKey(String encryptedData, String privateKeyBase64) throws Exception {
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyBase64);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decodedData = Base64.getDecoder().decode(encryptedData);
        byte[] decryptedData = cipher.doFinal(decodedData);
        return new String(decryptedData, "UTF-8");
    }

    /**
     * 私钥签名
     * @param data 待签名数据
     * @param privateKeyBase64 私钥（Base64编码）
     * @return 签名（Base64编码）
     * @throws Exception 异常
     */
    public static String sign(String data, String privateKeyBase64) throws Exception {
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyBase64);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

        Signature signature = Signature.getInstance(SIGN_ALGORITHM);
        signature.initSign(privateKey);
        signature.update(data.getBytes("UTF-8"));
        byte[] signedData = signature.sign();
        return Base64.getEncoder().encodeToString(signedData);
    }

    /**
     * 公钥验证签名
     * @param data 原始数据
     * @param signBase64 签名（Base64编码）
     * @param publicKeyBase64 公钥（Base64编码）
     * @return 是否验证通过
     * @throws Exception 异常
     */
    public static boolean verify(String data, String signBase64, String publicKeyBase64) throws Exception {
        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyBase64);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        PublicKey publicKey = keyFactory.generatePublic(keySpec);

        Signature signature = Signature.getInstance(SIGN_ALGORITHM);
        signature.initVerify(publicKey);
        signature.update(data.getBytes("UTF-8"));
        byte[] signBytes = Base64.getDecoder().decode(signBase64);
        return signature.verify(signBytes);
    }

    /**
     * 获取当前服务器需要额外校验的License参数
     */
//    public static LicenseCheckModel getServerInfos() {
//        //操作系统类型0 ：windows 1：linux 2：mac 3：其他
//        String osName = System.getProperty("os.name").toLowerCase();
//        AbstractServerInfos abstractServerInfos = null;
//
//        //根据不同操作系统类型选择不同的数据获取方法
//        if (osName.startsWith("windows")) {
//            abstractServerInfos = new WindowsServerInfos();
//        } else if (osName.startsWith("linux")) {
//            abstractServerInfos = new LinuxServerInfos();
//        } else {//其他服务器类型
//            abstractServerInfos = new LinuxServerInfos();
//        }
//
//        return abstractServerInfos.getServerInfos();
//    }
}